package wallegame.gui;

import static wallegame.Constants.END_FUEL;
import static wallegame.Constants.END_SPACESHIP;
import static wallegame.Constants.QUIT;
import static wallegame.Constants.TITLE_GAME;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;

import wallegame.RobotEngineObserver;

public class MainWindow extends JApplet implements RobotEngineObserver {

	/**
     * 
     */
	private static final long serialVersionUID = 1L;
	private NavigationPanel navigationPanel;
	private InstructionPanel instructionsPanel;
	private InfoPanel infoPanel;
	private GUIController guiController;
	private JPanel mainPanel;
	private boolean end = false;
	private JFrame container;
	private static final Dimension PREF_SIZE = new Dimension(900, 700);

	/**
	 * Creates the window and the panels using Swing Components. It stores a
	 * reference to the RobotEngine object and provides the panels to the robot
	 * engine in order to communicate the simulation events.
	 * 
	 * @param guiController
	 *            The RobotEngine that receives the instructions performed by
	 *            the action panel
	 */

	public MainWindow(GUIController guiController) {

		this.guiController = guiController;
		this.container = new JFrame();
		this.setPreferredSize(PREF_SIZE);
		container.setTitle(TITLE_GAME);
		container.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		mainPanel = new JPanel(new BorderLayout());

		createMenu();

		RobotPanel robotPanel = new RobotPanel();
		this.navigationPanel = new NavigationPanel();
		this.infoPanel = new InfoPanel();
		instructionsPanel = new InstructionPanel(guiController, robotPanel,
				this);
		JSplitPane SuperiorPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
				instructionsPanel, robotPanel);

		mainPanel.add(SuperiorPanel, BorderLayout.NORTH);

		JSplitPane inferiorPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
				SuperiorPanel, this.navigationPanel);
		mainPanel.add(inferiorPanel, BorderLayout.CENTER);
		mainPanel.add(infoPanel, BorderLayout.SOUTH);

		container.add(mainPanel);

		container.pack();
		container.setLocationRelativeTo(null);
		container.setVisible(true);

		this.add(container);

		guiController.registerRobotObserver(infoPanel);
		guiController.registerRobotObserver(this);
		guiController.registerRobotObserver(robotPanel);
		guiController.registerInventoryObserver(infoPanel);
		guiController.registerInventoryObserver(robotPanel);
		guiController.registerNavObserver(infoPanel);
		guiController.registerNavObserver(navigationPanel);

	}

	public JPanel getMainPanel() {
		return mainPanel;
	}

	public static Dimension getPrefSize() {
		return PREF_SIZE;
	}

	/**
	 * Create dialog menu for window
	 */

	public void createMenu() {
		JMenuBar mbMenu = new JMenuBar();
		this.setJMenuBar(mbMenu);
		JMenu mDialogs = new JMenu("File");
		mbMenu.add(mDialogs);
		initializeMenu(mDialogs);
	}

	/**
	 * 
	 * Quit from menu of window
	 * 
	 * @param mDialogs
	 *            menu for window
	 * 
	 */

	private void initializeMenu(JMenu mDialogs) {

		JMenuItem mQuit = new JMenuItem("Quit");
		mDialogs.add(mQuit);
		mQuit.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				JOptionPane.showMessageDialog(null, "Game Over");
				System.exit(0);

			}
		});
	}

	/**
	 * 
	 * Return a public method (end) of a private attribute (isEnd).
	 * 
	 * @return isEnd if game finish or not.
	 * 
	 */

	public boolean isEnd() {
		return end;
	}

	/**
	 * The robot engine informs that the robot has shut down (because it has
	 * arrived at the spaceship or it has run out of fuel)
	 * 
	 * Show different message dialog at interface mode if robot is at space ship
	 * or robot hasn't got fuel
	 * 
	 * @param ship
	 *            boolean true if the robot shuts down because it has arrived at
	 *            the spaceship or false if it has run out of fuel
	 */

	public void engineOff(boolean ship) {
		if (ship) {
			JOptionPane.showMessageDialog(rootPane, END_SPACESHIP);
			end = true;
		} else {
			JOptionPane.showMessageDialog(rootPane, END_FUEL);
			end = true;
		}
		this.instructionsPanel.setEnabled(false);
	}

	/**
	 * The robot engine informs that the help has been requested
	 */

	@Override
	public void communicationCompleted() {
		JOptionPane.showMessageDialog(rootPane, QUIT);

	}

	/**
	 * The robot engine informs that the help has been requested
	 * 
	 * @param help
	 *            A string with information help
	 */

	@Override
	public void communicationHelp(String help) {
		// Not use

	}

	/**
	 * The robot engine informs that it has raised an error
	 * 
	 * @param msg
	 *            Error message
	 */

	@Override
	public void raiseError(String msg) {
		JOptionPane.showMessageDialog(rootPane, msg);

	}

	/**
	 * The robot engine informs that the robot wants to say something
	 * 
	 * @param message
	 *            The robot message
	 */

	@Override
	public void robotSays(String message) {
		infoPanel.robotSays(message);
	}

	/**
	 * The robot engine informs that the fuel and/or the amount of recycled
	 * material has changed
	 * 
	 * @param fuel
	 *            Current amount of fuel
	 * @param recycledMaterial
	 *            Current amount of recycled material
	 */

	@Override
	public void robotUpdate(int fuel, int recycledMaterial) {
		// Not use
	}

	public void init() {
		try {
			javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
				public void run() {
					
				}
			});
		} catch (Exception e) {
			System.err.println("createGUI didn't successfully complete");
		}
	}

}